home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / emu / uniq.lha / uniq.c next >
Encoding:
C/C++ Source or Header  |  1994-04-01  |  8.0 KB  |  321 lines

  1. /* UNIQ.C
  2.  *
  3.  * Source Code by Oliver Kaufmann
  4.  *
  5.  * $VER: uniq 1.02 (25.3.1994) © by Oliver Kaufmann
  6.  *
  7.  * Compile with Manx Aztec or any other C-Compiler
  8.  *
  9.  */
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <dos/dos.h>
  13. #include <functions.h>
  14.  
  15. void CloseAll(char *s);
  16. char *makename(char *s, int blen, int elen, char **tb, char **tex, char *buffer);
  17. char *modifyname(char *tb, int blen, int elen, long sernum, int origlen);
  18. char *savestring(char *s);
  19. struct tbl *feedtbl(char *s, struct tbl *firsttbl);
  20. struct tbl *lookup(char *t, struct tbl *firsttbl, struct tbl *excludetbl);
  21. struct tbl *modifytbl(char *s, char *t, struct tbl *thistbl);
  22. struct tbl *inserttbl(char *s, char *t, struct tbl *firsttbl);
  23. struct tbl *uniq(struct tbl *thistbl, struct tbl *firsttbl,int blen, int elen);
  24. struct tbl *makeuniq(struct tbl *firsttbl, int blen, int elen);
  25. void giveout(struct tbl *firsttbl, char *lformat, int allflag);
  26.  
  27.  
  28. char ver[] = "$VER: uniq 1.02 (25.3.1994) © by Oliver Kaufmann";
  29. char *usage = "uniq [-d[<dir>]] [-a] [-f] [-l<lformat>] -p<pattern> -b<basenamelength> -e<extensionlength>\n\
  30.             -d<dir> : use contents of <dir> as input, otherwise use stdin\n\
  31.                  -a : print all names, even those which do not change\n\
  32.                  -f : process files only, no dirs (requires -d option)\n\
  33.         -l<lformat> : use <lformat> for formated output (\"rename %s %s\")\n\
  34.         -p<pattern> : pattern to apply (default #?)\n\
  35.  -b<basenamelength> : max. length of the uniqified string (default 8)\n\
  36. -e<extensionlength> : max. length of the uniqified extension (default 3)\n";
  37.  
  38.  
  39. struct tbl {
  40.    char *orig;
  41.    char *new;
  42.    struct tbl *nexttbl;
  43. };
  44.  
  45. struct MyAnchorPath {
  46.     struct AChain    *ap_Base;    /* pointer to first anchor */
  47.     struct AChain    *ap_Last;    /* pointer to last anchor */
  48.     LONG    ap_BreakBits;        /* Bits we want to break on */
  49.     LONG    ap_FoundBreak;        /* Bits we broke on. Also returns ERROR_BREAK */
  50.     BYTE    ap_Flags;        /* New use for extra word. */
  51.     BYTE    ap_Reserved;
  52.     WORD    ap_Strlen;        /* This is what ap_Length used to be */
  53.     struct    FileInfoBlock ap_Info;
  54.     UBYTE    ap_Buf[256];        /* Buffer for path name, allocated by user */
  55. };
  56.  
  57. struct FileInfoBlock *fib;
  58. struct MyAnchorPath myap;
  59. struct AnchorPath *ap;
  60.  
  61.  
  62. struct FileInfoBlock finfo;
  63.  
  64. #define BUFLEN 256
  65.  
  66. char pbuf[BUFLEN];
  67.  
  68. void main(int argc, char *argv[])
  69. {
  70.    struct tbl *firsttbl=NULL;
  71.    BPTR lock, oldlock;
  72.    char lbuf[BUFLEN];
  73.  
  74.    int allfilendirs = 1;
  75.    int allflag  = 0;
  76.    int blen=8;
  77.    int elen=3;
  78.    char *dirname=NULL;
  79.    char *lformat = "rename %s %s";
  80.    char *pattern="#?";
  81.  
  82.    char *s, *opt;
  83.    int i, res;
  84.  
  85.    for(i=1; i<argc; i++) {
  86.        if( *(opt=argv[i]) == '-') {
  87.           switch(opt[1]) {
  88.              case 'd' : dirname = &opt[2]; break;
  89.              case 'a' : allflag = 1      ; break;
  90.              case 'f' : allfilendirs = 0 ; break;
  91.              case 'l' : lformat = &opt[2]; break;
  92.              case 'p' : pattern = &opt[2]; break;
  93.              case 'b' : if( (blen = atoi(&opt[2]) ) <= 0)
  94.                            CloseAll("basenamelength must be > 0");
  95.                         break;
  96.              case 'e' : if( (elen = atoi(&opt[2])) < 0)
  97.                            CloseAll("extensionlength must be >= 0");
  98.                         break;
  99.              default  : printf("unknown option: ignored\n");
  100.                         break;
  101.           }
  102.        } else if( *opt == '?')
  103.           CloseAll(usage);
  104.    }
  105.  
  106.    if(dirname != NULL) {
  107.       if( (lock=Lock(dirname,ACCESS_READ)) == 0)
  108.           CloseAll("no lock on dir");
  109.       oldlock = CurrentDir(lock);
  110.       
  111.       ap = (struct AnchorPath*)&myap;
  112.       ap->ap_Strlen = 254;
  113.       ap->ap_BreakBits = 0;
  114.  
  115.       if ( MatchFirst(pattern, ap) )
  116.          CloseAll("MatchFirst: no match");
  117.  
  118.       do { 
  119.          fib = &ap->ap_Info;
  120.          if( allfilendirs || (fib->fib_DirEntryType < 0) ) /* exclude dirs on demand */
  121.             firsttbl = feedtbl(fib->fib_FileName, firsttbl);
  122.       } while (!MatchNext(ap));
  123.  
  124.       MatchEnd(ap);
  125.       CurrentDir(oldlock);
  126.       UnLock(lock);
  127.    } else {
  128.       if( ParsePattern(pattern, pbuf, BUFLEN) == -1)
  129.          CloseAll("pattern too long");
  130.       while( (res=scanf("%s",lbuf)) != EOF) {
  131.          if(res==0)
  132.             CloseAll("res = 0");
  133.          if(MatchPattern(pbuf, lbuf))                      /* nur wenn pattern matched */
  134.             firsttbl = feedtbl(lbuf, firsttbl);
  135.       }
  136.    }
  137.  
  138.    if( (firsttbl=makeuniq(firsttbl, blen, elen)) == NULL)
  139.       CloseAll("unable to uniqify");
  140.  
  141.  
  142.    giveout(firsttbl, lformat, allflag);
  143.  
  144.    CloseAll(NULL);
  145. }
  146.  
  147. struct tbl *makeuniq(struct tbl *firsttbl, int blen, int elen)
  148. {
  149.    struct tbl *thistbl;
  150.  
  151.    thistbl = firsttbl;
  152.  
  153.    while(thistbl != NULL) {
  154.       if( uniq(thistbl, firsttbl, blen, elen) == NULL)
  155.          return NULL;
  156.       
  157.       thistbl = thistbl->nexttbl;
  158.    }
  159.    return firsttbl;
  160. }
  161.  
  162. struct tbl *uniq(struct tbl *thistbl, struct tbl *firsttbl,int blen, int elen)
  163. {
  164.    char lbuf[BUFLEN];
  165.    char buffer[BUFLEN];
  166.  
  167.    char *t, *tb, *tex;
  168.    char *s;
  169.  
  170.    long sernum;
  171.    int origlen;
  172.  
  173.    s = thistbl->orig;
  174.    makename(s, blen, elen, &tb, &tex, buffer);              /* name und extension */
  175.    origlen = strlen(tb);                          /* base name length */
  176.  
  177.    for(sernum = 0; ; sernum++) { 
  178.       strcpy(lbuf,tb);
  179.       strcat(lbuf,tex);
  180.       if( lookup(lbuf, firsttbl, thistbl) == NULL )
  181.          break;
  182.       if( modifyname(tb, blen, elen, sernum, origlen) == 0)
  183.          return NULL;
  184.    }
  185.  
  186.    t = savestring(lbuf);
  187.  
  188.    modifytbl(s, t, thistbl);
  189.  
  190.    return thistbl;
  191. }
  192.  
  193. struct tbl *inserttbl(char *s, char *t, struct tbl *firsttbl)
  194. {
  195.    struct tbl *thistbl;
  196.  
  197.    if( (thistbl=malloc(sizeof(struct tbl))) == NULL)
  198.       CloseAll("no memory for tbl");
  199.  
  200.    thistbl->orig = s;
  201.    thistbl->new = t;
  202.    thistbl->nexttbl = firsttbl;
  203.    return thistbl;
  204.  
  205. }
  206.  
  207. struct tbl *modifytbl(char *s, char *t, struct tbl *thistbl)
  208. {
  209.    thistbl->orig = s;
  210.    thistbl->new = t;
  211.    return thistbl;
  212. }
  213.  
  214. struct tbl *feedtbl(char *s, struct tbl *firsttbl)
  215. {
  216.    char *m;
  217.  
  218.    m = savestring(s);
  219.    return inserttbl(m, m, firsttbl);
  220. }
  221.  
  222. char *savestring(char *s)
  223. {
  224.    char *mem;
  225.  
  226.    if( (mem=malloc(strlen(s)+1)) == NULL)
  227.       CloseAll("no memory for string");
  228.  
  229.    strcpy(mem, s);
  230.    return mem;
  231. }
  232.  
  233. struct tbl *lookup(char *t, struct tbl *firsttbl, struct tbl *excludetbl)
  234. {
  235.    while(firsttbl != NULL) {
  236.       if( (strcmp(t, firsttbl->new) == 0) && (firsttbl != excludetbl) )
  237.          break;
  238.       firsttbl = firsttbl->nexttbl;
  239.    }
  240.    return firsttbl;
  241. }
  242.  
  243.  
  244. char *modifyname(char *tb, int blen, int elen, long sernum, int origlen)
  245. {
  246.    char lbuf[BUFLEN];
  247.    int sl, i, j, pos;
  248.  
  249.    sprintf(lbuf,"%x",sernum);
  250.    if( (sl = strlen(lbuf)) > blen )      /* sernum zu groß */
  251.       return NULL;
  252.  
  253.    pos = origlen;
  254.    if( origlen + sl > blen )
  255.       pos = blen-sl;
  256.    strncpy(tb+pos, lbuf, sl);
  257.    return tb;
  258. }
  259.  
  260. char *makename(char *s, int blen, int elen, char **tb, char **tex, char *buffer)
  261. {
  262.    char *t;
  263.    int n,m;
  264.    int sl,i;
  265.  
  266.    *tb = buffer;
  267.  
  268.    for(n=0, t=s ; (*t != '\0') && (*t != '.') ; *t++, n++);
  269.  
  270.    strncpy(buffer, s, n);             /* es wird evtl mehr kopiert */
  271.  
  272.    while(n<blen)
  273.       buffer[n++] = '\0';              /* auffüllen */
  274.  
  275.    buffer[blen] = '\0';               /* rest abschneiden */
  276.  
  277.    n = blen+1;                        /* ab hier extension */
  278.  
  279.    buffer[n] = '\0';                  /* default ist leer */
  280.  
  281.    *tex = &buffer[n];
  282.  
  283.    if(elen != 0 ) {
  284.       
  285.       for(i = sl = strlen(s)-1; sl >= 0; sl--)
  286.          if(s[sl] == '.')
  287.             break;
  288.       if(s[sl] == '.') {
  289.          buffer[n++] = '.';
  290.          strncpy(&buffer[n], &s[sl+1], i-sl+1); /* 0 mitkopieren */
  291.          n += i-sl;
  292.       }
  293.  
  294.       buffer[n] = '\0';                  /* default ist leer */
  295.       buffer[blen+elen+1+1]='\0';
  296.  
  297.    }
  298.       
  299.    return *tb;
  300.  
  301. }
  302.  
  303. void giveout(struct tbl *firsttbl, char *lformat, int allflag)
  304. {
  305.    while (firsttbl != NULL) {
  306.       if( allflag || strcmp(firsttbl->orig, firsttbl->new) ) {
  307.          printf(lformat,firsttbl->orig, firsttbl->new);
  308.          printf("\n");
  309.       }
  310.       firsttbl = firsttbl->nexttbl;
  311.    }
  312. }
  313.  
  314.  
  315. void CloseAll(char *s)
  316. {
  317.    if(s != NULL)
  318.       printf("%s\n",s);
  319.    exit(0);
  320. }
  321.